package website.haicheng.cloudauth.controller;


import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import website.haicheng.cloudauth.dto.LoginDto;
import website.haicheng.cloudauth.dto.UserInfoDto;
import website.haicheng.cloudauth.entity.UserInfo;
import website.haicheng.cloudauth.service.IMenuService;
import website.haicheng.cloudauth.service.IRoleInfoService;
import website.haicheng.cloudauth.service.IUserInfoService;
import website.haicheng.cloudauth.vo.UserInfoVo;
import website.haicheng.core.base.Resp;
import website.haicheng.core.constant.RedisPrefix;
import website.haicheng.core.util.JWTUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 582895699@qq.com
 * @since 2021-02-10
 */
@Api(tags = "用户接口")
@RestController
@RequestMapping("/user")
public class UserInfoController {

    public static final String SEPARATE = ":";

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private IRoleInfoService roleInfoService;

    @Autowired
    private IMenuService menuService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Resp.class), @ApiResponse(code = 500, message = "失败")})
    @ApiOperation(value = "登录并获取Token")
    @PostMapping(value = "/login")
    public Resp login(@Validated @RequestBody LoginDto loginDto, HttpServletRequest request) {
        UserInfo currentUser = userInfoService.login(loginDto, request);
        String token = JWTUtil.createToken(loginDto.getAccount(), currentUser.getId());
        Map<String, String> data = Maps.newHashMapWithExpectedSize(1);
        data.put("token", token);
        redisTemplate.opsForValue().set(RedisPrefix.AUTH_MODULE_PREFIX + SEPARATE + token, token, 1L, TimeUnit.HOURS);
        return Resp.ok(data);
    }

    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Resp.class), @ApiResponse(code = 500, message = "失败")})
    @ApiOperation(value = "退出登录")
    @GetMapping(value = "/logout")
    public Resp logout(HttpServletRequest request) {
        String token = JWTUtil.getTokenFromHeader(request);
        redisTemplate.delete(RedisPrefix.AUTH_MODULE_PREFIX + SEPARATE + token);
        return Resp.ok();
    }


    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = UserInfoVo.class), @ApiResponse(code = 500, message = "失败")})
    @ApiOperation(value = "通过token获取用户信息")
    @GetMapping(value = "/getUserInfo")
    public Resp getUserInfo(HttpServletRequest request) {
        UserInfoVo vo = new UserInfoVo();
        int userId = JWTUtil.getUserIdFromToken(request);

        UserInfo userInfo = userInfoService.getById(userId);
        BeanUtils.copyProperties(userInfo, vo);

        Set<String> roles = roleInfoService.listRoleName(userId);
        vo.setRoles(roles);

        Set<String> permissions = menuService.listPermission(userId);
        vo.setPermissions(permissions);
        return Resp.ok(vo);
    }

    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Resp.class), @ApiResponse(code = 500, message = "失败")})
    @ApiOperation(value = "通过token删除用户")
    @DeleteMapping
    public Resp delUser(HttpServletRequest request) {
        int userId = JWTUtil.getUserIdFromToken(request);
        return Resp.ok();
    }


    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Resp.class), @ApiResponse(code = 500, message = "失败")})
    @ApiOperation(value = "添加用户")
    @PostMapping(value = "/addUser")
    public Resp addUser(@Validated @RequestBody UserInfoDto dto) {
        return Resp.ok();
    }
}
